package com.vf.s.mvc.sync.common.task.http.handle;

import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;

import com.jfinal.ext.kit.DateKit;
import com.jfinal.kit.StrKit;
import com.vf.core.render.RenderBean;
import com.vf.core.util.UuidUtil;
import com.vf.s.common.model.biz.BizLayer;
import com.vf.s.common.model.biz.BizPoint;
import com.vf.s.common.model.sync.BizSyncDataLog;
import com.vf.s.common.model.sync.BizSyncDataProcess;
import com.vf.s.common.model.sync.BizSyncDataTask;
import com.vf.s.mvc.sync.common.model.DataTotal;
import com.vf.s.mvc.sync.common.model.Point;
import com.vf.s.mvc.sync.common.task.http.HttpUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;


public class PointExecutor {

	private ExecutorService executor = Executors.newFixedThreadPool(1000);
	
	public void handle(BizLayer bizLayer,BizSyncDataTask task,DataTotal dataTotal,long totalPage) {
		
		BizSyncDataLog syncDataLog=new BizSyncDataLog();
		syncDataLog.setId(UuidUtil.getUUID());
		syncDataLog.setTaskId(task.getId());
		syncDataLog.setStartTime(new Date(System.currentTimeMillis()));
		syncDataLog.setTotal((int)dataTotal.getSize());
		syncDataLog.setPages((int)totalPage);
		syncDataLog.setStatus("0");
		syncDataLog.save();
		
		CompletableFuture<Integer> future;
		@SuppressWarnings("unchecked")
		CompletableFuture<Integer>[] cfs=new CompletableFuture[(int)totalPage];
		for(int i=1;i<=totalPage;i++) {
			int curPage=i;
			future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
				@Override
				public Integer get() {
					try {
						// 开始执行
						BizSyncDataProcess process = new BizSyncDataProcess();
						process.setId(UuidUtil.getUUID());
						process.setTaskId(task.getId());
						process.setStatus("0");
						process.setCurPage(curPage);
						process.setStartTime(task.getLastTime());
						process.setStopTime(dataTotal.getTime());
						process.save();
						RenderBean result;
						if (StrKit.equals("GET", task.getMethod())) {
							result=HttpUtil.doGet(
									task.getUrl(), task.getId(), task.getCode(),task.getName(),
									DateKit.toStr(task.getLastTime(), "yyyy-MM-dd hh:mm:ss "),
									DateKit.toStr(dataTotal.getTime(), "yyyy-MM-dd hh:mm:ss ")
									,1,
									task.getParam(),curPage, task.getPageSize());
							savePoint( bizLayer, process, result);
						} else {
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					return (int)totalPage;
				}
			}, executor);
			cfs[i-1]=future;
		}
		
	CompletableFuture<Void> all=CompletableFuture.allOf(cfs);
		if(all!=null) {
			//阻塞，直到所有任务结束。
	        System.out.println(System.currentTimeMillis() + ":阻塞");
	        all.join();
	        
	        syncDataLog.setStatus("1");
	        syncDataLog.update();
	        task.setLastTime(dataTotal.getTime());
	        System.out.println(System.currentTimeMillis() + ":阻塞结束");
		}
	}
	
	private void savePoint(BizLayer bizLayer,BizSyncDataProcess process,RenderBean result) {
		if(result.getCode()!=200) {
			process.setRemark(result.getMessage());
			process.setStatus("5");
			process.setStopTime(new Date(System.currentTimeMillis()));
			process.update();
			return;
		}
		try {
			JSONArray jsonArray=JSONArray.fromObject(result.getData());
			if(jsonArray!=null && jsonArray.size()>0) {
				Point pointModel;
				BizPoint bizPoint;
				BizPoint oldBizPoint;
				process.setPageSize(jsonArray.size());
				process.update();
				
				int i=1;
				int update=1;
				int insert=1;
				int delete=1;
				for(Object jsonObject:jsonArray) {
					pointModel = (Point) JSONObject.toBean( JSONObject.fromObject(jsonObject), Point.class);
					if(pointModel!=null) {
						if(!StrKit.equals("1", pointModel.getIsDel())) {
							bizPoint=new BizPoint();
							bizPoint.setId(pointModel.getId());
							bizPoint.setName(pointModel.getName());
							bizPoint.setCode(pointModel.getCode());
							bizPoint.setX(pointModel.getX());
							bizPoint.setY(pointModel.getY());
							bizPoint.setZ(pointModel.getZ());
							bizPoint.setLayerId(bizLayer.getId());
							oldBizPoint=BizPoint.dao.findById(pointModel.getId());
							if(oldBizPoint!=null) {
								if(bizPoint.update()) {
									process.setSuccTotal(i);
									process.setUpdateTotal(update);
									process.update();
									i++;
									update++;
								}
							}else {
								if(bizPoint.save()) {
									process.setSuccTotal(i);
									process.setInsertTotal(insert);
									process.update();
									i++;
									insert++;
								}
							}
						}else {
							if(BizPoint.dao.deleteById(pointModel.getId())) {
								process.setSuccTotal(i);
								process.setDeleteTotal(delete);
								process.update();
								i++;
								delete++;
							}
						}
					}
				}
				process.setRemark(result.getMessage());
				process.setStatus("1");
				process.setStopTime(new Date(System.currentTimeMillis()));
				process.update();
			}else {
				process.setRemark(result.getMessage());
				process.setStatus("1");
				process.setStopTime(new Date(System.currentTimeMillis()));
				process.update();
			}
		}catch (Exception e) {
			process.setRemark(e.getMessage());
			process.setStatus("5");
			process.setStopTime(new Date(System.currentTimeMillis()));
			process.update();
		}
	}
	

}
